1
2
3
4
5
6
7 package io.vavr.collection.euler;
8
9 import io.vavr.Function1;
10 import io.vavr.collection.CharSeq;
11 import io.vavr.collection.List;
12 import io.vavr.collection.Stream;
13 import org.assertj.core.api.Assertions;
14 import org.junit.Test;
15
16 import static io.vavr.collection.euler.Utils.file;
17 import static io.vavr.collection.euler.Utils.readLines;
18 import static org.assertj.core.api.Assertions.assertThat;
19
20 public class Euler42Test {
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 @Test
45 public void shouldSolveProblem42() {
46 assertThat(isTriangleWord("SKY")).isTrue();
47 assertThat(sumOfAlphabeticalPositions("SKY")).isEqualTo(55);
48 assertThat(alphabeticalPosition('S')).isEqualTo(19);
49 assertThat(alphabeticalPosition('K')).isEqualTo(11);
50 assertThat(alphabeticalPosition('Y')).isEqualTo(25);
51 assertThat(TRIANGLE_NUMBERS.take(10)).containsExactly(1, 3, 6, 10, 15, 21, 28, 36, 45, 55);
52 List.rangeClosed(1, 60).forEach(n -> Assertions.assertThat(isTriangleNumberMemoized.apply(n)).isEqualTo(List.of(1, 3, 6, 10, 15, 21, 28, 36, 45, 55).contains(n)));
53
54 assertThat(numberOfTriangleNumbersInFile()).isEqualTo(162);
55 }
56
57 private static int numberOfTriangleNumbersInFile() {
58 return readLines(file("p042_words.txt"))
59 .map(l -> l.replaceAll("\"", ""))
60 .flatMap(l -> List.of(l.split(",")))
61 .filter(Euler42Test::isTriangleWord)
62 .length();
63 }
64
65 private static boolean isTriangleWord(String word) {
66 return isTriangleNumber(sumOfAlphabeticalPositions(word));
67 }
68
69 private static boolean isTriangleNumber(int n) {
70 return TRIANGLE_NUMBERS
71 .takeWhile(t -> t <= n)
72 .exists(t -> t == n);
73 }
74
75 private static final Function1<Integer, Boolean> isTriangleNumberMemoized = Function1.of(Euler42Test::isTriangleNumber).memoized();
76
77 private static final Stream<Integer> TRIANGLE_NUMBERS = Stream.from(1).map(n -> 0.5 * n * (n + 1)).map(Double::intValue);
78
79 private static int sumOfAlphabeticalPositions(String word) {
80 return CharSeq.of(word)
81 .map(Euler42Test::alphabeticalPosition)
82 .sum().intValue();
83 }
84
85 private static int alphabeticalPosition(char c) {
86 return c - 'A' + 1;
87 }
88 }